import base64
import datetime
import json
import re

import requests

from Crypto.Cipher import PKCS1_v1_5 as PKCS1_cipher
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA

class Server:
    def __init__(self, url_head, user_key):
        self.url_head = url_head
        self.user_key = user_key

ServerLocalRelease = Server(
    "http://192.168.1.11:8080/gateway",
    "2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0d4d4947664d413047435371475349623344514542415155414134474e4144434269514b426751444d623377614f6a6151414c5831766b677132636456783773360d3935536443474e484c494b2f53673658704b534c45314e495272485454336e6b7342556b30314673334777794b7a4a555964612f59646f4f454646506a7178420d704e3853446b4c51796f74334845342f5669723130696f4c675665517572314a7469447966664a4a6e4e2f47734e4d4575586963707a6b7379423942437072520d7861643245315563425252504a574b564d774944415141420d2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0d")
ServerRemoteRelease = Server(
    "https://visitdd.cn/gateway",
    "2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0d4d4947664d413047435371475349623344514542415155414134474e4144434269514b42675143366877665958626e6b57384b5737596a6a516a57644d756d640d36772b48697a5556386d7675513648554b553941666a417a2b4867365970462b696f7268695664466941363733757863353654786b4b51376a4b454d782b4b6b0d704c464866447a6e464b4279714f46514e796b6154494f5a5a3634337756756867694a335051786f52384247526c6e706c4a382b6c3439524b3452534e586d670d4f474931576e345437596d46414e4a3877774944415141420d2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0d")
ServerDebug = Server(
    "http://127.0.0.1:8080/gateway",
    "2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0d4d4947664d413047435371475349623344514542415155414134474e4144434269514b4267514371716b7457594b7256524d4968324652635a53356c4e6b726c0d5568456a466a7162467338615048332f474c78642f664959672b654149745365305a64537254583969504a7776582b4c7268687961367138354b4e616b63346b0d556d564f4e4a435166485a37566370336c647962344e5767454c625179524a4c47647046435a31752f4a7239683953416634424f4530575737516442377572630d3452595372384f346e2b485442654d3266514944415141420d2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0d")

# For Debug
# URL_HEAD = "http://127.0.0.1:8080/gateway"
# USER_KEY = "2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0d4d4947664d413047435371475349623344514542415155414134474e4144434269514b4267514371716b7457594b7256524d4968324652635a53356c4e6b726c0d5568456a466a7162467338615048332f474c78642f664959672b654149745365305a64537254583969504a7776582b4c7268687961367138354b4e616b63346b0d556d564f4e4a435166485a37566370336c647962344e5767454c625179524a4c47647046435a31752f4a7239683953416634424f4530575737516442377572630d3452595372384f346e2b485442654d3266514944415141420d2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0d"

SERVER_PUB_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu9KeWBap4YzhIT1uJ58cokigZWqyxlCQ9lueblsxEvchJmntOaLLF3rrvwdFd7e+0e2QCAx07vLtWK1g/yPl9QVyAH6toJtA+Xtou4CtJ78+8eW/mvRKhwi4IIYHlpgVXEBUYZ/ruCTlNg+tQgSRV2TBZI25x6UZZZmH6a5nSzqcQeL2C+QQfYzmjPFxmrHN0A4HmplKduaBOAAhFg2+7wD6JBYp7CI8UyFn4qPZmVNBIR9MdFw2mpM5YR9GZuy4exl+us9FyJB7E4XxAYCgASLSh/MO/fd4e8iuaY2Sz5cI5Hv7GofbVXaUXMA3oUmEVGqrQGi45fCCJubavMyJOQIDAQAB"
RSA_KEY_BIN = base64.b64decode(SERVER_PUB_KEY)
# 从字节数据中加载公钥
RSA_KEY = RSA.importKey(RSA_KEY_BIN)
# print(RSA_KEY.size_in_bytes())
# 计算每组可加密的最大长度（使用PKCS#1 v1.5填充模式）
max_block_size = RSA_KEY.size_in_bytes() - 11  # PKCS#1 v1.5填充需要11字节

def __encrypt_long_message(message):
    """
    对过长的消息进行分组加密
    :param public_key: RSA公钥
    :param message: 要加密的消息
    :return: 加密后的消息
    """
    # print(len(message))
    cipher = PKCS1_cipher.new(RSA_KEY)
    encrypted_blocks = []
    # 按最大块大小对消息进行分组
    for i in range(0, len(message), max_block_size):
        block = message[i:i + max_block_size]
        # 对每个分组进行加密
        encrypted_block = cipher.encrypt(block)
        encrypted_blocks.append(encrypted_block)
    # 将所有加密后的分组拼接起来
    encrypted_message = b''.join(encrypted_blocks)
    return encrypted_message


def __gen_http_header(server:Server):
    token_salt = datetime.datetime.now().date().strftime("%y%m%d")
    hasher = SHA256.new()
    # 更新哈希器内容
    hasher.update((server.user_key + token_salt).encode())
    # 完成哈希计算并获取结果
    hash_result = hasher.hexdigest()
    headers = {
        'Token-Type': '1',
        'Token-Salt': token_salt,
        'Token-Hash': hash_result
    }
    # print(headers)
    return headers


def batch_add(tag, json, server:Server):
    url = server.url_head + "/batch-add/" + tag
    encrypted = __encrypt_long_message(json.encode())
    encrypted = base64.b64encode(encrypted)
    # 发送 POST 请求
    response = requests.post(url, headers=__gen_http_header(server), data=encrypted, verify=False)
    # 检查响应状态码
    response.raise_for_status()
    # 获取响应内容
    response_data = response.text
    print(response_data)


def batch_modify(tag, json, server:Server):
    url = server.url_head + "/batch-modify/" + tag
    encrypted = __encrypt_long_message(json.encode())
    encrypted = base64.b64encode(encrypted)
    # 发送 POST 请求
    response = requests.post(url, headers=__gen_http_header(server), data=encrypted, verify=False)
    # 检查响应状态码
    response.raise_for_status()
    # 获取响应内容
    response_data = response.text
    print(response_data)


"""
pub const C_FVE_EQ: u16 = 11;
pub const C_FVE_PART_MATCH: u16 = 12;
pub const C_FVE_START_WITH: u16 = 15;
pub const C_FVE_END_WITH: u16 = 16;
pub const C_FVE_BETWEEN: u16 = 13;
pub const C_FVE_IN: u16 = 14;
pub const C_FVE_NOT_EQ: u16 = 21;
pub const C_FVE_NOT_CONTAIN: u16 = 22;
pub const C_FVE_OUT_RANGE: u16 = 23;
pub const C_FVE_NOT_IN: u16 = 24;
"""


def page(tag, json, print_res=False, server:Server=ServerRemoteRelease):
    url = server.url_head + "/page/" + tag
    data = base64.b64encode(json.encode())
    response = requests.post(url, headers=__gen_http_header(server), data=data, verify=False)
    # 检查响应状态码
    response.raise_for_status()
    # 获取响应内容
    response_data = response.text
    if print_res:
        print(response_data)
    return response_data


def check_exist(tag, json, print_res=False, server:Server=ServerRemoteRelease):
    url = server.url_head + "/check-exist/" + tag
    data = base64.b64encode(json.encode())
    response = requests.post(url, headers=__gen_http_header(server), data=data, verify=False)
    # 检查响应状态码
    response.raise_for_status()
    # 获取响应内容
    response_data = response.text
    if print_res:
        print(response_data)
    return response_data

def export_fv(tag, field, print_res = False, server:Server = ServerRemoteRelease):
    url = server.url_head + "/export-fv/" + tag + "?field="+field
    response = requests.get(url, headers=__gen_http_header(server), verify=False)
    # response = requests.get(url='http://127.0.0.1:8080/api/v1/prometheus',headers=gen_http_header(server))
    status_code = response.status_code
    content = response.text
    if print_res:
        print(status_code)
        print(content)
    return content

def export_grouped_fv(tag:str, key_field:str, value_field:str, print_res:bool = False, server:Server = ServerRemoteRelease):
    url = server.url_head + "/export-grouped-fv/" + tag
    data = {"kf":key_field, "vf":value_field}
    data = base64.b64encode(json.dumps(data).encode())
    response = requests.post(url, headers=__gen_http_header(server), data=data, verify=False)
    # response = requests.get(url='http://127.0.0.1:8080/api/v1/prometheus',headers=gen_http_header(server))
    status_code = response.status_code
    content = response.text
    if print_res:
        print(status_code)
        print(content)
    return content

def is_icd10_code(s):
    icd_10_code_pattern = re.compile(r'^[A-Z]\d+(\.\d+)(x\d+)*(\+\S+\*)*')
    return re.match(icd_10_code_pattern, s)


def is_icd9_code(s):
    icd_9_code_pattern = re.compile(r'^\d+\.\d+(x\d+)?')
    return re.match(icd_9_code_pattern, s)
